#region License Information

#endregion

#region Using Directives

using Fusion8.Cropper.Extensibility;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Text;

#endregion

namespace CropperPlugins	
{
    public class TimeCapture:IPersistableImageFormat, IConfigurablePlugin
    {
        [DllImport("user32.dll")]
        static extern int GetForegroundWindow();

        [DllImport("user32.dll")]
        static extern int GetWindowText(int hWnd, StringBuilder text, int count); 

        private System.Threading.Timer _recordTimer;
        IPersistableOutput m_persistableOutput;
        public TimeCapture()
        {
            
        }
        #region IPersistableImageFormat Members

        public void Connect(IPersistableOutput persistableOutput)
        {
            if (persistableOutput != null)
            {
                m_persistableOutput = persistableOutput;
                m_persistableOutput.ImageCaptured += new ImageCapturedEventHandler(m_persistableOutput_ImageCaptured);
                m_persistableOutput.ImageCapturing += new ImageCapturingEventHandler(m_persistableOutput_ImageCapturing);
            }
        }
        bool record ;
        string description;
        void m_persistableOutput_ImageCapturing(object sender, ImageCapturingEventArgs e)
        {
            if (record)
            {
                description = "Time Capture - Recording";
            }
            else
            {
                description = "Time Capture - Stopped";
            }
        }

        void m_persistableOutput_ImageCaptured(object sender, ImageCapturedEventArgs e)
        {
//            MessageBox.Show(e.ImageNames.FullSize);
            NameFolder = Path.GetDirectoryName(e.ImageNames.FullSize);
            record = !record;
            if (record)
            {
                Start();
            }
            else
            {
                Stop();
            }
            
        }

        

        public string Description
        {
            get 
            {
                return description + " [Andrei Ignat]";
            }
        }

        public void Disconnect()
        {
            m_persistableOutput.ImageCaptured -= new ImageCapturedEventHandler(m_persistableOutput_ImageCaptured);
            m_persistableOutput.ImageCapturing -= new ImageCapturingEventHandler(m_persistableOutput_ImageCapturing);
            m_persistableOutput = null;
        }
        //TODO: more that 1 extension
        public string Extension
        {
            get { return "Png"; }
        }

        public IPersistableImageFormat Format
        {
            get { return this; }
        }

        public event ImageFormatClickEventHandler ImageFormatClick;

        public MenuItem Menu
        {
            get 
            {
                MenuItem item = new MenuItem();
                item.RadioCheck = true;
                item.Text = "Time Capture";
                item.Click += new EventHandler(item_Click);
                return item;
            }
        }
        public override string ToString()
        {
            return "Time Capturing [Andrei Ignat]";
        }
        string NameFolder;
        private void item_Click(object sender, EventArgs e)
        {
            try
            {
                ImageFormatEventArgs args = new ImageFormatEventArgs();
                args.ClickedMenuItem = (MenuItem)sender;
                args.ImageOutputFormat = this;
                this.OnImageFormatClick(sender, args);
                
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

        }

        private void OnImageFormatClick(object sender, ImageFormatEventArgs e)
        {
            if (this.ImageFormatClick != null)
            {
                this.ImageFormatClick(sender, e);
            }
        }
        #endregion

        #region IConfigurablePlugin Members
        private TimeCap t;
        public BaseConfigurationForm ConfigurationForm
        {
            get 
            {
                if (t == null)
                {
                    t = new TimeCap();
                    t.Seconds = SettingsTime.SecTime;
                    t.RecordActiveWindowText = SettingsTime.RecordActiveWindowText;
                    t.OptionsSaved += new EventHandler(t_OptionsSaved);
                    
                }
                return t;
            }
        }
        private TimeSettings ts;
        private TimeSettings SettingsTime
        {
            get
            {
                if (ts == null)
                    ts = new TimeSettings();

                return ts;
            }
            set
            {
                ts = value as TimeSettings;
            }
        }
        void t_OptionsSaved(object sender, EventArgs e)
        {
            SettingsTime.SecTime = t.Seconds;
            SettingsTime.RecordActiveWindowText = t.RecordActiveWindowText;
            SettingsTime.Save();
        }
        private void Start()
        {
            if (_recordTimer != null)
            {
                
                _recordTimer = null;
            }
            
            _recordTimer = new System.Threading.Timer(new TimerCallback(Tick), m_persistableOutput,0, SettingsTime.SecTime * 1000);
            
        }
        private void Stop()
        {
            if(_recordTimer != null)
                _recordTimer.Dispose();


            _recordTimer = null;
        }
        private void Tick(object state)
        {
            IPersistableOutput m = state as IPersistableOutput;
            if (m != null)
            {
                m.FetchCapture(new ImageHandler(SaveImage));                
            }
        }
        // http://www.codeproject.com/dotnet/comparingimages.asp
        private string GetHashFromImage(Image image)
        {
            System.Drawing.ImageConverter ic = new System.Drawing.ImageConverter();
            byte[] imageBytes = new byte[1];
            imageBytes = (byte[])ic.ConvertTo(image, imageBytes.GetType());
            System.Security.Cryptography.MD5CryptoServiceProvider md5 =
                new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] hashBytes = md5.ComputeHash(imageBytes);
            return BitConverter.ToString(hashBytes);
        }
        string _previousHash;
        private void SaveImage(Image i)
        {
            string currentHash = GetHashFromImage(i);	
			//Check if image has changed from previous
            if (_previousHash == null || currentHash != _previousHash)
            {
                
                
                DateTime dt = DateTime.Now;
                string CaptureDir = Path.Combine(NameFolder, "CaptureTime");
                if (!Directory.Exists(CaptureDir))
                    Directory.CreateDirectory(CaptureDir);

                CaptureDir = Path.Combine(CaptureDir, dt.ToString("yyyyMMdd"));

                if (!Directory.Exists(CaptureDir))
                    Directory.CreateDirectory(CaptureDir);

                string NameFile=Path.Combine(CaptureDir, "capture_" + DateTime.Now.ToString("yyyyMMdd_hhmmss"));
                if (SettingsTime.RecordActiveWindowText)
                {
                    try
                    {
                        const int nChars = 256;
                        int handle = 0;
                        StringBuilder Buff = new StringBuilder(nChars);

                        handle = GetForegroundWindow();

                        if (GetWindowText(handle, Buff, nChars) > 0)
                        {
                            //File.WriteAllText(NameFile + ".txt", Buff.ToString());
                            File.WriteAllText(NameFile + ".txt", "prev" + _previousHash + Environment.NewLine + "curr" + currentHash);
                            

                        }

                    }
                    catch (Exception)
                    {

                    }
                }
                i.Save(NameFile + ".png", ImageFormat.Png);
            }
            _previousHash = currentHash;
        }
        
        public bool HostInOptions
        {
            get { return true; }
        }

        public object Settings
        {
            get
            {
                return SettingsTime;
            }
            set
            {
                Settings= value as TimeSettings;
            }
        }

        #endregion

        
    }
}
